home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 016a / gofer221.zip / PRELUDE < prev    next >
Text File  |  1991-11-20  |  26KB  |  789 lines

  1. --         __________   __________   __________   __________   ________
  2. --        /  _______/  /  ____   /  /  _______/  /  _______/  /  ____  \
  3. --       /  / _____   /  /   /  /  /  /______   /  /______   /  /___/  /
  4. --      /  / /_   /  /  /   /  /  /  _______/  /  _______/  /  __   __/
  5. --     /  /___/  /  /  /___/  /  /  /         /  /______   /  /  \  \ 
  6. --    /_________/  /_________/  /__/         /_________/  /__/    \__\
  7. --
  8. --    Functional programming environment, Version 2.21
  9. --    Copyright Mark P Jones 1991.
  10. --
  11. --    Standard prelude for use of overloaded values using type classes.
  12. --    Based on the Haskell standard prelude version 1.1.
  13.  
  14. help = "press :? for a list of commands"
  15.  
  16. -- Operator precedence table: -----------------------------------------------
  17.  
  18. infixl 9 !!
  19. infixr 9 .
  20. infixr 8 ^
  21. infixl 7 *
  22. infix  7 /, `div`, `rem`, `mod`
  23. infixl 6 +, -
  24. infix  5 \\
  25. infixr 5 ++, :
  26. infix  4 ==, /=, <, <=, >=, >
  27. infix  4 `elem`, `notElem`
  28. infixr 3 &&
  29. infixr 2 ||
  30.  
  31. -- Standard combinators: ----------------------------------------------------
  32.  
  33. primitive strict "primStrict" :: (a -> b) -> a -> b
  34.  
  35. const          :: a -> b -> a
  36. const k x       = k
  37.  
  38. id             :: a -> a
  39. id    x         = x
  40.  
  41. curry          :: ((a,b) -> c) -> a -> b -> c
  42. curry f a b     =  f (a,b)
  43.  
  44. uncurry        :: (a -> b -> c) -> (a,b) -> c
  45. uncurry f (a,b) = f a b
  46.  
  47. fst            :: (a,b) -> a
  48. fst (x,_)       = x
  49.  
  50. snd            :: (a,b) -> b
  51. snd (_,y)       = y
  52.  
  53. fst3           :: (a,b,c) -> a
  54. fst3 (x,_,_)    = x
  55.  
  56. snd3           :: (a,b,c) -> b
  57. snd3 (_,x,_)    = x
  58.  
  59. thd3           :: (a,b,c) -> c
  60. thd3 (_,_,x)    = x
  61.  
  62. (.)           :: (b -> c) -> (a -> b) -> (a -> c)
  63. (f . g) x       = f (g x)
  64.  
  65. flip           :: (a -> b -> c) -> b -> a -> c
  66. flip  f x y     = f y x
  67.  
  68. -- Boolean functions: -------------------------------------------------------
  69.  
  70. (&&), (||)     :: Bool -> Bool -> Bool
  71. False && x      = False
  72. True  && x      = x
  73.  
  74. False || x      = x
  75. True  || x      = True
  76.  
  77. not            :: Bool -> Bool
  78. not True        = False
  79. not False       = True
  80.  
  81. and, or        :: [Bool] -> Bool
  82. and             = foldr (&&) True
  83. or              = foldr (||) False
  84.  
  85. any, all       :: (a -> Bool) -> [a] -> Bool
  86. any p           = or  . map p
  87. all p           = and . map p
  88.  
  89. otherwise      :: Bool
  90. otherwise       = True
  91.  
  92. -- Character functions: -----------------------------------------------------
  93.  
  94. primitive ord "primCharToInt" :: Char -> Int
  95. primitive chr "primIntToChar" :: Int -> Char
  96.  
  97.  
  98. isAscii, isControl, isPrint, isSpace            :: Char -> Bool
  99. isUpper, isLower, isAlpha, isDigit, isAlphanum  :: Char -> Bool
  100.  
  101. isAscii c     =  ord c < 128
  102.  
  103. isControl c   =  c < ' '    ||  c == '\DEL'
  104.  
  105. isPrint c     =  c >= ' '   &&  c <= '~'
  106.  
  107. isSpace c     =  c == ' '   || c == '\t'  || c == '\n'  || c == '\r'  ||
  108.                                c == '\f'  || c == '\v'
  109.  
  110. isUpper c     =  c >= 'A'   &&  c <= 'Z'
  111. isLower c     =  c >= 'a'   &&  c <= 'z'
  112.  
  113. isAlpha c     =  isUpper c  ||  isLower c
  114. isDigit c     =  c >= '0'   &&  c <= '9'
  115. isAlphanum c  =  isAlpha c  ||  isDigit c
  116.  
  117.  
  118. toUpper, toLower      :: Char -> Char
  119.  
  120. toUpper c | isLower c  = chr (ord c - ord 'a' + ord 'A')
  121.           | otherwise  = c
  122.  
  123. toLower c | isUpper c  = chr (ord c - ord 'A' + ord 'a')
  124.           | otherwise  = c
  125.  
  126. -- Standard type classes: ---------------------------------------------------
  127.  
  128. class Eq a where
  129.     (==), (/=) :: a -> a -> Bool
  130.     x /= y      = not (x == y)
  131.  
  132. class Eq a => Ord a where
  133.     (<), (<=), (>), (>=) :: a -> a -> Bool
  134.     max, min             :: a -> a -> a
  135.  
  136.     x <  y            = x <= y && x /= y
  137.     x >= y            = y <= x
  138.     x >  y            = y < x
  139.  
  140.     max x y | x >= y  = x
  141.             | y >= x  = y
  142.     min x y | x <= y  = x
  143.             | y <= x  = y
  144.  
  145. class Ord a => Ix a where
  146.     range   :: (a,a) -> [a]
  147.     index   :: (a,a) -> a -> Int
  148.     inRange :: (a,a) -> a -> Bool
  149.  
  150. class Ord a => Enum a where
  151.     enumFrom       :: a -> [a]              -- [n..]
  152.     enumFromThen   :: a -> a -> [a]         -- [n,m..]
  153.     enumFromTo     :: a -> a -> [a]         -- [n..m]
  154.     enumFromThenTo :: a -> a -> a -> [a]    -- [n,n'..m]
  155.  
  156.     enumFromTo n m        = takeWhile (m>=) (enumFrom n)
  157.     enumFromThenTo n n' m = takeWhile ((if n'>=n then (>=) else (<=)) m)
  158.                                       (enumFromThen n n')
  159.  
  160. class Eq a => Num a where               -- simplified numeric class
  161.     (+), (-), (*), (/) :: a -> a -> a
  162.     negate             :: a -> a
  163.     fromInteger           :: Int -> a
  164.  
  165. -- Type class instances: ----------------------------------------------------
  166.  
  167. primitive primEqInt    "primEqInt",
  168.       primLeInt    "primLeInt"   :: Int -> Int -> Bool
  169. primitive primPlusInt  "primPlusInt",
  170.       primMinusInt "primMinusInt",
  171.       primDivInt   "primDivInt",
  172.       primMulInt   "primMulInt"  :: Int -> Int -> Int
  173. primitive primNegInt   "primNegInt"  :: Int -> Int
  174.  
  175. instance Eq Int  where (==) = primEqInt
  176.  
  177. instance Ord Int where (<=) = primLeInt
  178.  
  179. instance Ix Int where
  180.     range (m,n)      = [m..n]
  181.     index (m,n) i    = i - m
  182.     inRange (m,n) i  = m <= i && i <= n
  183.  
  184. instance Enum Int where
  185.     enumFrom n       = iterate (1+) n
  186.     enumFromThen n m = iterate ((m-n)+) n
  187.  
  188. instance Num Int where
  189.     (+)           = primPlusInt
  190.     (-)           = primMinusInt
  191.     (*)           = primMulInt
  192.     (/)           = primDivInt
  193.     negate        = primNegInt
  194.     fromInteger x = x
  195.  
  196. {- PC version off -}
  197. primitive primEqFloat    "primEqFloat",
  198.           primLeFloat    "primLeFloat"    :: Float -> Float -> Bool
  199. primitive primPlusFloat  "primPlusFloat", 
  200.           primMinusFloat "primMinusFloat", 
  201.           primDivFloat   "primDivFloat",
  202.           primMulFloat   "primMulFloat"   :: Float -> Float -> Float 
  203. primitive primNegFloat   "primNegFloat"   :: Float -> Float
  204. primitive primIntToFloat "primIntToFloat" :: Int -> Float
  205.  
  206. instance Eq Float where (==) = primEqFloat
  207.  
  208. instance Ord Float where (<=) = primLeFloat
  209.  
  210. instance Enum Float where
  211.     enumFrom n       = iterate (1.0+) n
  212.     enumFromThen n m = iterate ((m-n)+) n
  213.  
  214. instance Num Float where
  215.     (+)         = primPlusFloat
  216.     (-)         = primMinusFloat
  217.     (*)         = primMulFloat
  218.     (/)         = primDivFloat 
  219.     negate      = primNegFloat
  220.     fromInteger = primIntToFloat
  221. {- PC version on -}
  222.  
  223. instance Eq Char where c == d  =  ord c == ord d
  224.  
  225. instance Ord Char where c <= d  =  ord c <= ord d
  226.  
  227. instance Ix Char where
  228.     range (c,c')      = [c..c']
  229.     index (c,c') ci   = ord ci - ord c
  230.     inRange (c,c') ci = ord c <= i && i <= ord c' where i = ord ci
  231.  
  232. instance Enum Char where
  233.     enumFrom c        = map chr [ord c ..]
  234.     enumFromThen c c' = map chr [ord c, ord c' ..]
  235.  
  236. instance Eq a => Eq [a] where
  237.     []     == []     =  True
  238.     []     == (y:ys) =  False
  239.     (x:xs) == []     =  False
  240.     (x:xs) == (y:ys) =  x==y && xs==ys
  241.  
  242. instance Ord a => Ord [a] where
  243.     []     <= _      =  True
  244.     (_:_)  <= []     =  False
  245.     (x:xs) <= (y:ys) =  x<y || (x==y && xs<=ys)
  246.  
  247. instance (Eq a, Eq b) => Eq (a,b) where
  248.     (x,y) == (u,v)  =  x==u && y==v
  249.  
  250. instance (Ord a, Ord b) => Ord (a,b) where
  251.     (x,y) <= (u,v)  = x<u  ||  (x==u && y<=v)
  252.  
  253. instance Eq Bool where
  254.     True  == True   =  True
  255.     False == False  =  True
  256.     _     == _      =  False
  257.  
  258. -- Standard numerical functions: --------------------------------------------
  259.  
  260. primitive div    "primDivInt",
  261.           rem    "primRemInt",
  262.           mod    "primModInt"    :: Int -> Int -> Int
  263.  
  264. subtract  :: Num a => a -> a -> a
  265. subtract   = flip (-)
  266.  
  267. even, odd :: Int -> Bool
  268. even x     = x `rem` 2 == 0
  269. odd        = not . even
  270.  
  271. gcd       :: Int -> Int -> Int
  272. gcd x y    = gcd' (abs x) (abs y)
  273.              where gcd' x 0 = x
  274.                    gcd' x y = gcd' y (x `rem` y)
  275.  
  276. lcm       :: Int -> Int -> Int
  277. lcm _ 0    = 0
  278. lcm 0 _    = 0
  279. lcm x y    = abs ((x `div` gcd x y) * y)
  280.  
  281. (^)       :: Int -> Int -> Int
  282. x ^ 0      = 1
  283. x ^ (n+1)  = f x n x
  284.              where f _ 0 y = y
  285.                    f x n y = g x n where
  286.                              g x n | even n    = g (x*x) (n`div`2)
  287.                                    | otherwise = f x (n-1) (x*y)
  288.  
  289. abs :: Int -> Int
  290. abs x    | x >= 0  = x
  291.          | x <  0  = - x
  292.  
  293. signum :: Int -> Int
  294. signum x | x == 0  = 0
  295.          | x > 0   = 1
  296.          | x < 0   = -1
  297.  
  298. sum, product    :: [Int] -> Int
  299. sum              = foldl' (+) 0
  300. product          = foldl' (*) 1
  301.  
  302. sums, products    :: [Int] -> [Int]
  303. sums             = scanl (+) 0
  304. products         = scanl (*) 1
  305.  
  306. -- Standard list processing functions: --------------------------------------
  307.  
  308. head             :: [a] -> a
  309. head (x:_)        = x
  310.  
  311. last             :: [a] -> a
  312. last [x]          = x
  313. last (_:xs)       = last xs
  314.  
  315. tail             :: [a] -> [a]
  316. tail (_:xs)       = xs
  317.  
  318. init             :: [a] -> [a]
  319. init [x]          = []
  320. init (x:xs)       = x : init xs
  321.  
  322. (++)             :: [a] -> [a] -> [a]    -- append lists.  Associative with
  323. []     ++ ys      = ys                   -- left and right identity [].
  324. (x:xs) ++ ys      = x:(xs++ys)
  325.  
  326. length         :: [a] -> Int           -- calculate length of list
  327. length            = foldl' (\n _ -> n+1) 0
  328.  
  329. (!!)             :: [a] -> Int -> a      -- xs!!n selects the nth element of
  330. (x:_)  !! 0       = x                    -- the list xs (first element xs!!0)
  331. (_:xs) !! (n+1)   = xs !! n              -- for any n < length xs.
  332.  
  333. iterate          :: (a -> a) -> a -> [a] -- generate the infinite list
  334. iterate f x       = x : iterate f (f x)  -- [x, f x, f (f x), ...
  335.  
  336. repeat           :: a -> [a]             -- generate the infinite list
  337. repeat x          = xs where xs = x:xs   -- [x, x, x, x, ...
  338.  
  339. cycle            :: [a] -> [a]           -- generate the infinite list
  340. cycle xs          = xs' where xs'=xs++xs'-- xs ++ xs ++ xs ++ ...
  341.  
  342. copy             :: Int -> a -> [a]      -- make list of n copies of x
  343. copy n x          = take n xs where xs = x:xs
  344.  
  345. nub              :: Eq a => [a] -> [a]   -- remove duplicates from list
  346. nub []            = []
  347. nub (x:xs)        = x : nub (filter (x/=) xs)
  348.  
  349. reverse          :: [a] -> [a]           -- reverse elements of list
  350. reverse           = foldl (flip (:)) []
  351.  
  352. elem, notElem    :: Eq a => a -> [a] -> Bool
  353. elem              = any . (==)           -- test for membership in list
  354. notElem           = all . (/=)           -- test for non-membership
  355.  
  356. maximum, minimum :: Ord a => [a] -> a
  357. maximum           = foldl1 max          -- max element in non-empty list
  358. minimum           = foldl1 min          -- min element in non-empty list
  359.  
  360. concat           :: [[a]] -> [a]        -- concatenate list of lists
  361. concat            = foldr (++) []
  362.  
  363. transpose        :: [[a]] -> [[a]]      -- transpose list of lists
  364. transpose         = foldr
  365.                       (\xs xss -> zipWith (:) xs (xss ++ repeat []))
  366.                       []
  367.  
  368. -- null provides a simple and efficient way of determining whether a given
  369. -- list is empty, without using (==) and hence avoiding a constraint of the
  370. -- form Eq [a].
  371.  
  372. null             :: [a] -> Bool
  373. null []           = True
  374. null (_:_)        = False
  375.  
  376. -- (\\) is used to remove the first occurrence of each element in the second
  377. -- list from the first list.  It is a kind of inverse of (++) in the sense
  378. -- that  (xs ++ ys) \\ xs = ys for any finite list xs of proper values xs.
  379.  
  380. (\\)             :: Eq a => [a] -> [a] -> [a]
  381. (\\)              = foldl del
  382.                     where []     `del` _  = []
  383.                           (x:xs) `del` y
  384.                              | x == y     = xs
  385.                              | otherwise  = x : xs `del` y
  386.  
  387.  
  388. -- map f xs applies the function f to each element of the list xs returning
  389. -- the corresponding list of results.  filter p xs returns the sublist of xs
  390. -- containing those elements which satisfy the predicate p.
  391.  
  392. map              :: (a -> b) -> [a] -> [b]
  393. map f []          = []
  394. map f (x:xs)      = f x : map f xs
  395.  
  396. filter           :: (a -> Bool) -> [a] -> [a]
  397. filter _ []       = []
  398. filter p (x:xs)
  399.     | p x         = x : xs'
  400.     | otherwise   = xs'
  401.                   where xs' = filter p xs
  402.  
  403. -- Fold primitives:  The foldl and scanl functions, variants foldl1 and
  404. -- scanl1 for non-empty lists, and strict variants foldl' scanl' describe
  405. -- common patterns of recursion over lists.  Informally:
  406. --
  407. --  foldl f a [x1, x2, ..., xn]  = f (...(f (f a x1) x2)...) xn
  408. --                               = (...((a `f` x1) `f` x2)...) `f` xn
  409. -- etc...
  410. --
  411. -- The functions foldr, scanr and variants foldr1, scanr1 are duals of these
  412. -- functions:
  413. -- e.g.  foldr f a xs = foldl (flip f) a (reverse xs)  for finite lists xs.
  414.  
  415. foldl            :: (a -> b -> a) -> a -> [b] -> a
  416. foldl f z []      = z
  417. foldl f z (x:xs)  = foldl f (f z x) xs
  418.  
  419. foldl1           :: (a -> a -> a) -> [a] -> a
  420. foldl1 f (x:xs)   = foldl f x xs
  421.  
  422. foldl'           :: (a -> b -> a) -> a -> [b] -> a
  423. foldl' f a []     =  a
  424. foldl' f a (x:xs) =  strict (foldl' f) (f a x) xs
  425.  
  426. scanl            :: (a -> b -> a) -> a -> [b] -> [a]
  427. scanl f q xs      = q : (case xs of
  428.                          []   -> []
  429.                          x:xs -> scanl f (f q x) xs)
  430.  
  431. scanl1           :: (a -> a -> a) -> [a] -> [a]
  432. scanl1 f (x:xs)   = scanl f x xs
  433.  
  434. scanl'           :: (a -> b -> a) -> a -> [b] -> [a]
  435. scanl' f q xs     = q : (case xs of
  436.                          []   -> []
  437.                          x:xs -> strict (scanl' f) (f q x) xs)
  438.  
  439. foldr            :: (a -> b -> b) -> b -> [a] -> b
  440. foldr f z []      = z
  441. foldr f z (x:xs)  = f x (foldr f z xs)
  442.  
  443. foldr1           :: (a -> a -> a) -> [a] -> a
  444. foldr1 f [x]      = x
  445. foldr1 f (x:xs)   = f x (foldr1 f xs)
  446.  
  447. scanr            :: (a -> b -> b) -> b -> [a] -> [b]
  448. scanr f q0 []     = [q0]
  449. scanr f q0 (x:xs) = f x q : qs
  450.                     where qs@(q:_) = scanr f q0 xs
  451.  
  452. scanr1           :: (a -> a -> a) -> [a] -> [a]
  453. scanr1 f [x]      = [x]
  454. scanr1 f (x:xs)   = f x q : qs
  455.                     where qs@(q:_) = scanr1 f xs
  456.  
  457. -- List breaking functions:
  458. --
  459. --   take n xs       returns the first n elements of xs
  460. --   drop n xs       returns the remaining elements of xs
  461. --   splitAt n xs    = (take n xs, drop n xs)
  462. --
  463. --   takeWhile p xs  returns the longest initial segment of xs whose
  464. --                   elements satisfy p
  465. --   dropWhile p xs  returns the remaining portion of the list
  466. --   span p xs       = (takeWhile p xs, dropWhile p xs)
  467. --
  468. --   takeUntil p xs  returns the list of elements upto and including the
  469. --                   first element of xs which satisfies p
  470.  
  471. take                :: Int -> [a] -> [a]
  472. take 0     _         = []
  473. take _     []        = []
  474. take (n+1) (x:xs)    = x : take n xs
  475.  
  476. drop                :: Int -> [a] -> [a]
  477. drop 0     xs        = xs
  478. drop _     []        = []
  479. drop (n+1) (_:xs)    = drop n xs
  480.  
  481. splitAt             :: Int -> [a] -> ([a], [a])
  482. splitAt 0     xs     = ([],xs)
  483. splitAt _     []     = ([],[])
  484. splitAt (n+1) (x:xs) = (x:xs',xs'') where (xs',xs'') = splitAt n xs
  485.  
  486. takeWhile           :: (a -> Bool) -> [a] -> [a]
  487. takeWhile p []       = []
  488. takeWhile p (x:xs)
  489.          | p x       = x : takeWhile p xs
  490.          | otherwise = []
  491.  
  492. takeUntil           :: (a -> Bool) -> [a] -> [a]
  493. takeUntil p []       = []
  494. takeUntil p (x:xs)
  495.        | p x         = [x]
  496.        | otherwise   = x : takeUntil p xs
  497.  
  498. dropWhile           :: (a -> Bool) -> [a] -> [a]
  499. dropWhile p []       = []
  500. dropWhile p xs@(x:xs')
  501.          | p x       = dropWhile p xs'
  502.          | otherwise = xs
  503.  
  504. span, break         :: (a -> Bool) -> [a] -> ([a],[a])
  505. span p []            = ([],[])
  506. span p xs@(x:xs')
  507.          | p x       = let (ys,zs) = span p xs' in (x:ys,zs)
  508.          | otherwise = ([],xs)
  509. break p              = span (not . p)
  510.  
  511. -- Text processing:
  512. --   lines s     returns the list of lines in the string s.
  513. --   words s     returns the list of words in the string s.
  514. --   unlines ls  joins the list of lines ls into a single string
  515. --               with lines separated by newline characters.
  516. --   unwords ws  joins the list of words ws into a single string
  517. --               with words separated by spaces.
  518.  
  519. lines     :: String -> [String]
  520. lines ""   = []
  521. lines s    = l : (if null s' then [] else lines (tail s'))
  522.              where (l, s') = break ('\n'==) s
  523.  
  524. words     :: String -> [String]
  525. words s    = case dropWhile isSpace s of
  526.                   "" -> []
  527.                   s' -> w : words s''
  528.                         where (w,s'') = break isSpace s'
  529.  
  530. unlines   :: [String] -> String
  531. unlines    = concat . map (\l -> l ++ "\n")
  532.  
  533. unwords   :: [String] -> String
  534. unwords [] = []
  535. unwords ws = foldr1 (\w s -> w ++ ' ':s) ws
  536.  
  537. -- Merging and sorting lists:
  538.  
  539. merge               :: Ord a => [a] -> [a] -> [a] 
  540. merge []     ys      = ys
  541. merge xs     []      = xs
  542. merge (x:xs) (y:ys)
  543.         | x <= y     = x : merge xs (y:ys)
  544.         | otherwise  = y : merge (x:xs) ys
  545.  
  546. sort                :: Ord a => [a] -> [a]
  547. sort                 = foldr insert []
  548.  
  549. insert              :: Ord a => a -> [a] -> [a]
  550. insert x []          = [x]
  551. insert x (y:ys)
  552.         | x <= y     = x:y:ys
  553.         | otherwise  = y:insert x ys
  554.  
  555. qsort               :: Ord a => [a] -> [a]
  556. qsort []             = []
  557. qsort (x:xs)         = qsort [ u | u<-xs, u<x ] ++
  558.                              [ x ] ++
  559.                        qsort [ u | u<-xs, u>=x ]
  560.  
  561. -- zip and zipWith families of functions:
  562.  
  563. zip  :: [a] -> [b] -> [(a,b)]
  564. zip   = zipWith  (\a b -> (a,b))
  565.  
  566. zip3 :: [a] -> [b] -> [c] -> [(a,b,c)]
  567. zip3  = zipWith3 (\a b c -> (a,b,c))
  568.  
  569. zip4 :: [a] -> [b] -> [c] -> [d] -> [(a,b,c,d)]
  570. zip4  = zipWith4 (\a b c d -> (a,b,c,d))
  571.  
  572. zip5 :: [a] -> [b] -> [c] -> [d] -> [e] -> [(a,b,c,d,e)]
  573. zip5  = zipWith5 (\a b c d e -> (a,b,c,d,e))
  574.  
  575. zip6 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a,b,c,d,e,f)]
  576. zip6  = zipWith6 (\a b c d e f -> (a,b,c,d,e,f))
  577.  
  578. zip7 :: [a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g] -> [(a,b,c,d,e,f,g)]
  579. zip7  = zipWith7 (\a b c d e f g -> (a,b,c,d,e,f,g))
  580.  
  581.  
  582. zipWith                  :: (a->b->c) -> [a]->[b]->[c]
  583. zipWith z (a:as) (b:bs)   = z a b : zipWith z as bs
  584. zipWith _ _      _        = []
  585.  
  586. zipWith3                 :: (a->b->c->d) -> [a]->[b]->[c]->[d]
  587. zipWith3 z (a:as) (b:bs) (c:cs)
  588.                           = z a b c : zipWith3 z as bs cs
  589. zipWith3 _ _ _ _          = []
  590.  
  591. zipWith4                 :: (a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e]
  592. zipWith4 z (a:as) (b:bs) (c:cs) (d:ds)
  593.                           = z a b c d : zipWith4 z as bs cs ds
  594. zipWith4 _ _ _ _ _        = []
  595.  
  596. zipWith5                 :: (a->b->c->d->e->f) -> [a]->[b]->[c]->[d]->[e]->[f]
  597. zipWith5 z (a:as) (b:bs) (c:cs) (d:ds) (e:es)
  598.                           = z a b c d e : zipWith5 z as bs cs ds es
  599. zipWith5 _ _ _ _ _ _      = []
  600.  
  601. zipWith6                 :: (a->b->c->d->e->f->g)
  602.                             -> [a]->[b]->[c]->[d]->[e]->[f]->[g]
  603. zipWith6 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs)
  604.                           = z a b c d e f : zipWith6 z as bs cs ds es fs
  605. zipWith6 _ _ _ _ _ _ _    = []
  606.  
  607. zipWith7                 :: (a->b->c->d->e->f->g->h)
  608.                              -> [a]->[b]->[c]->[d]->[e]->[f]->[g]->[h]
  609. zipWith7 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs) (g:gs)
  610.                           = z a b c d e f g : zipWith7 z as bs cs ds es fs gs
  611. zipWith7 _ _ _ _ _ _ _ _  = []
  612.  
  613. -- Formatted output: --------------------------------------------------------
  614.  
  615. primitive primPrint "primPrint"  :: Int -> a -> String -> String
  616.  
  617. show'       :: a -> String
  618. show' x      = primPrint 0 x []
  619.  
  620. cjustify, ljustify, rjustify :: Int -> String -> String
  621.  
  622. cjustify n s = space halfm ++ s ++ space (m - halfm)
  623.                where m     = n - length s
  624.                      halfm = m `div` 2
  625. ljustify n s = s ++ space (n - length s)
  626. rjustify n s = space (n - length s) ++ s
  627.  
  628. space       :: Int -> String
  629. space n      = copy n ' '
  630.  
  631. layn        :: [String] -> String
  632. layn         = lay 1 where lay _ []     = []
  633.                            lay n (x:xs) = rjustify 4 (show n) ++ ") "
  634.                                            ++ x ++ "\n" ++ lay (n+1) xs
  635.  
  636. -- Miscellaneous: -----------------------------------------------------------
  637.  
  638. until                  :: (a -> Bool) -> (a -> a) -> a -> a
  639. until p f x | p x       = x
  640.             | otherwise = until p f (f x)
  641.  
  642. until'                 :: (a -> Bool) -> (a -> a) -> a -> [a]
  643. until' p f              = takeUntil p . iterate f
  644.  
  645. error                  :: String -> a
  646. error msg | False       = error msg
  647.  
  648. undefined              :: a
  649. undefined | False       = undefined
  650.  
  651. asTypeOf               :: a -> a -> a
  652. x `asTypeOf` _          = x
  653.  
  654. -- A trimmed down version of the Haskell Text class: ------------------------
  655.  
  656. type  ShowS   = String -> String
  657.  
  658. class Text a where 
  659.     showsPrec      :: Int -> a -> ShowS
  660.     showList       :: [a] -> ShowS
  661.  
  662.     showsPrec       = primPrint
  663.     showList []     = showString "[]"
  664.     showList (x:xs) = showChar '[' . shows x . showl xs
  665.                       where showl []     = showChar ']'
  666.                             showl (x:xs) = showChar ',' . shows x . showl xs
  667.  
  668. shows      :: Text a => a -> ShowS
  669. shows       =  showsPrec 0
  670.  
  671. show       :: Text a => a -> String
  672. show x      =  shows x ""
  673.  
  674. showChar   :: Char -> ShowS
  675. showChar    =  (:)
  676.  
  677. showString :: String -> ShowS
  678. showString  =  (++)
  679.  
  680. instance Text ()
  681.  
  682. instance Text Int
  683.  
  684. {- PC version off -}
  685. instance Text Float
  686. {- PC version on -}
  687.  
  688. instance Text Char where
  689.     showList cs = showChar '"' . showl cs
  690.                   where showl ""       = showChar '"'
  691.                         showl ('"':cs) = showString "\\\"" . showl cs
  692.                         showl (c:cs)   = showChar c . showl cs
  693.             -- Haskell has   showLitChar c . showl cs
  694.  
  695. instance Text a => Text [a]  where
  696.     showsPrec p = showList
  697.  
  698. instance (Text a, Text b) => Text (a,b) where
  699.     showsPrec p (x,y) = showChar '(' . shows x . showChar ',' .
  700.                                        shows y . showChar ')'
  701.  
  702. -- I/O functions and definitions: -------------------------------------------
  703.  
  704. stdin         =  "stdin"
  705. stdout        =  "stdout"
  706. stderr        =  "stderr"
  707. stdecho       =  "stdecho"
  708.  
  709. data Request  =  -- file system requests:
  710.                 ReadFile      String         
  711.               | WriteFile     String String
  712.               | AppendFile    String String
  713.                  -- channel system requests:
  714.               | ReadChan      String 
  715.               | AppendChan    String String
  716.                  -- environment requests:
  717.               | Echo          Bool
  718.  
  719. data Response = Success
  720.               | Str String 
  721.               | Failure IOError
  722.  
  723. data IOError  = WriteError   String
  724.               | ReadError    String
  725.               | SearchError  String
  726.               | FormatError  String
  727.               | OtherError   String
  728.  
  729. type Dialogue  =  [Response] -> [Request]
  730. type SuccCont  =                Dialogue
  731. type StrCont   =  String     -> Dialogue
  732. type FailCont  =  IOError    -> Dialogue
  733.  
  734. done          ::                                                Dialogue
  735. readFile      :: String ->           FailCont -> StrCont     -> Dialogue
  736. writeFile     :: String -> String -> FailCont -> SuccCont    -> Dialogue
  737. appendFile    :: String -> String -> FailCont -> SuccCont    -> Dialogue
  738. readChan      :: String ->           FailCont -> StrCont     -> Dialogue
  739. appendChan    :: String -> String -> FailCont -> SuccCont    -> Dialogue
  740. echo          :: Bool ->             FailCont -> SuccCont    -> Dialogue
  741.  
  742. done resps    =  []
  743. readFile name fail succ resps =
  744.      (ReadFile name) : strDispatch fail succ resps
  745. writeFile name contents fail succ resps =
  746.     (WriteFile name contents) : succDispatch fail succ resps
  747. appendFile name contents fail succ resps =
  748.     (AppendFile name contents) : succDispatch fail succ resps
  749. readChan name fail succ resps =
  750.     (ReadChan name) : strDispatch fail succ resps
  751. appendChan name contents fail succ resps =
  752.     (AppendChan name contents) : succDispatch fail succ resps
  753. echo bool fail succ resps =
  754.     (Echo bool) : succDispatch fail succ resps
  755.  
  756. strDispatch fail succ (resp:resps) = 
  757.             case resp of Str val     -> succ val resps
  758.                          Failure msg -> fail msg resps
  759.  
  760. succDispatch fail succ (resp:resps) = 
  761.             case resp of Success     -> succ resps
  762.                          Failure msg -> fail msg resps
  763.  
  764. abort           :: FailCont
  765. abort err        = done
  766.  
  767. exit            :: FailCont
  768. exit err         = appendChan stdout msg abort done
  769.                    where msg = case err of ReadError s   -> s
  770.                                            WriteError s  -> s
  771.                                            SearchError s -> s
  772.                                            FormatError s -> s
  773.                                            OtherError s  -> s
  774.  
  775. print           :: Text a => a -> Dialogue
  776. print x          = appendChan stdout (show x) abort done
  777.  
  778. prints          :: Text a => a -> String -> Dialogue
  779. prints x s       = appendChan stdout (shows x s) abort done
  780.  
  781. interact    :: (String -> String) -> Dialogue
  782. interact f     = readChan stdin abort
  783.                 (\x -> appendChan stdout (f x) abort done)
  784.  
  785. run        :: (String -> String) -> Dialogue
  786. run f         = echo False abort (interact f)
  787.  
  788. -- End of Gofer standard prelude: --------------------------------------------
  789.